﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.DirectoryServices;

namespace Ko2.Sys
{

    public class AD
    {

        #region Members

        Ko2.Portal.Env koEnv = new Ko2.Portal.Env();

        #endregion

        #region App Settings
        public string GetAppSetting(String mName)
        {
            return koEnv.GetAppSetting(mName);
        }
        #endregion App Settings

        #region Common

        public string GetProperty(ref DirectoryEntry oDE, string PropertyName)
        {
            if (oDE.Properties.Contains(PropertyName))
            {
                return oDE.Properties[PropertyName][0].ToString();
            }
            else
            {
                return string.Empty;
            }
        }

        #endregion

        public Exception IsExistUserInGroup(ref Boolean IsExist, string uid, string GroupName)
        {
            string ADServer = GetAppSetting(@"ADServer");
            string ADAdminUser = GetAppSetting(@"ADUser");
            string ADAdminPassword = GetAppSetting(@"ADPass");

            return IsExistUserInGroup(ref IsExist, uid, ADServer, ADAdminUser, ADAdminPassword, GroupName);
        }
        public Exception IsExistUserInGroup(ref Boolean IsExist, string uid, string ADServer, string ADAdminUser, string ADAdminPassword, string GroupName)
        {
            Exception ret = null;
            IsExist = false;
            try
            {
                DirectoryEntry de = new DirectoryEntry(ADServer, ADAdminUser, ADAdminPassword);
                DirectorySearcher deSearch = new DirectorySearcher();
                deSearch.SearchRoot = de;
                deSearch.Filter = "(&(objectClass=group)(cn=" + GroupName + "))";

                SearchResult results = deSearch.FindOne();
                if (results != null)
                {
                    DirectoryEntry deGroup = new DirectoryEntry(results.Path, ADAdminUser, ADAdminPassword, AuthenticationTypes.Secure);
                    System.DirectoryServices.PropertyCollection pcoll = deGroup.Properties;
                    int n = pcoll["member"].Count;

                    for (int l = 0; l < n; l++)
                    {
                        DirectoryEntry deUser =
                            new DirectoryEntry(ADServer +
                                "/" + pcoll["member"][l].ToString()
                                    , ADAdminUser, ADAdminPassword, AuthenticationTypes.Secure);

                        string Login = GetProperty(ref deUser, "SAMACCOUNTNAME");
                        string USERACCOUNTCONTROL = GetProperty(ref deUser, "USERACCOUNTCONTROL");
                        deUser.Close();

                        if (USERACCOUNTCONTROL == "512" || USERACCOUNTCONTROL == "66048")
                        {
                            if (uid.ToUpper() == Login.ToUpper())
                            {
                                IsExist = true;
                                break;
                            }
                        }
                    }
                    de.Close();
                    deGroup.Close();
                }
            }
            catch (Exception err)
            {
                ret = new Exception(err.Message, err);
            }
            return ret;
        }

        public Exception GetUsersInGroup(ref DataTable tbUser, string GroupName)
        {
            string ADServer = GetAppSetting(@"ADServer");
            string ADAdminUser = GetAppSetting(@"ADUser");
            string ADAdminPassword = GetAppSetting(@"ADPass");

            return GetUsersInGroup(ref tbUser, ADServer, ADAdminUser, ADAdminPassword, GroupName);
        }
        public Exception GetUsersInGroup(ref DataTable tbUser, string GroupName, bool IsExtProp = false)
        {
            string ADServer = GetAppSetting(@"ADServer");
            string ADAdminUser = GetAppSetting(@"ADUser");
            string ADAdminPassword = GetAppSetting(@"ADPass");

            return GetUsersInGroup(ref tbUser, ADServer, ADAdminUser, ADAdminPassword, GroupName, IsExtProp);
        }
        public Exception GetUsersInGroup(ref DataTable tbUser, string ADServer, string ADAdminUser, string ADAdminPassword, string GroupName, bool IsExtProp = false)
        {
            Exception ret = null;
            try
            {
                //String strPath = "LDAP://DC=onecity,DC=corp,DC=fabrikam,DC=com";
                DirectoryEntry de = new DirectoryEntry(ADServer, ADAdminUser, ADAdminPassword);
                DirectorySearcher deSearch = new DirectorySearcher();
                deSearch.SearchRoot = de;
                //deSearch.PropertiesToLoad.Add("cn");
                deSearch.Filter = "(&(objectClass=group)(cn=" + GroupName + "))";
                SearchResult results = deSearch.FindOne();

                if (IsExtProp == true)
                    MakeTableUserExtProp(ref tbUser);
                else
                    MakeTableUserSimple(ref tbUser);

                if (results != null)
                {
                    DirectoryEntry deGroup = 
                        new DirectoryEntry(
                            results.Path
                            , ADAdminUser
                            , ADAdminPassword
                            , AuthenticationTypes.Secure);
                    System.DirectoryServices.PropertyCollection pcoll = deGroup.Properties;
                    int n = pcoll["member"].Count;
                    for (int l = 0; l < n; l++)
                    {
                        DirectoryEntry deUser = new DirectoryEntry(ADServer + "/" + pcoll["member"][l].ToString(), ADAdminUser, ADAdminPassword, AuthenticationTypes.Secure);
                        DataRow rwUser = tbUser.NewRow();
                        rwUser["Login"] = GetProperty(ref deUser, "SAMACCOUNTNAME");
                        rwUser["USERACCOUNTCONTROL"] = GetProperty(ref deUser, "USERACCOUNTCONTROL");
                        rwUser["UserName"] = GetProperty(ref deUser, "cn");
                        rwUser["DisplayName"] = GetProperty(ref deUser, "givenName") + " " + GetProperty(ref deUser, "sn");
                        rwUser["EMailAddress"] = GetProperty(ref deUser, "mail");
                        rwUser["Office"] = GetProperty(ref deUser, "PHYSICALDELIVERYOFFICENAME");

                        if (IsExtProp == true)
                        {
                            rwUser["SN"] = GetProperty(ref deUser, "SN");
                            rwUser["GIVENNAME"] = GetProperty(ref deUser, "GIVENNAME");
                            rwUser["EXTENSIONATTRIBUTE3"] = GetProperty(ref deUser, "EXTENSIONATTRIBUTE3");
                            rwUser["PHYSICALDELIVERYOFFICENAME"] = GetProperty(ref deUser, "PHYSICALDELIVERYOFFICENAME");
                            rwUser["EXTENSIONATTRIBUTE4"] = GetProperty(ref deUser, "EXTENSIONATTRIBUTE4");
                            rwUser["TELEPHONENUMBER"] = GetProperty(ref deUser, "TELEPHONENUMBER");
                            rwUser["TITLE"] = GetProperty(ref deUser, "TITLE");
                            rwUser["Department"] = GetProperty(ref deUser, "Department");
                            rwUser["Company"] = GetProperty(ref deUser, "Company");
                            rwUser["Manager"] = GetProperty(ref deUser, "Manager");
                        }

                        tbUser.Rows.Add(rwUser);
                        deUser.Close();
                    }
                    de.Close();
                    deGroup.Close();
                }
            }
            catch (Exception err)
            {
                ret = new Exception(err.Message, err);
            }
            return ret;
        }

        public Exception GetUsersInOffice(ref DataTable tbUser, string OfficeName)
        {
            string ADServer = GetAppSetting(@"ADServer");
            string ADAdminUser = GetAppSetting(@"ADUser");
            string ADAdminPassword = GetAppSetting(@"ADPass");
            return GetUsersInOffice(ref tbUser, ADServer, ADAdminUser, ADAdminPassword, OfficeName);
        }
        public Exception GetUsersInOffice(ref DataTable tbUser, string OfficeName, bool IsOnlyActived = true, bool IsExtProp = false)
        {
            string ADServer = GetAppSetting(@"ADServer");
            string ADAdminUser = GetAppSetting(@"ADUser");
            string ADAdminPassword = GetAppSetting(@"ADPass");
            return GetUsersInOffice(ref tbUser, ADServer, ADAdminUser, ADAdminPassword, OfficeName, IsOnlyActived, IsExtProp);
        }
        public Exception GetUsersInOffice(ref DataTable tbUser, string ADServer, string ADAdminUser, string ADAdminPassword, string OfficeName, bool IsOnlyActived = true, bool IsExtProp = false)
        {
            Exception ret = null;
            DirectoryEntry deUser = null;
            string strTmp = "";
            string strOffice = "";
            try
            {
                DirectorySearcher search =
                    new DirectorySearcher(
                        new DirectoryEntry(ADServer, ADAdminUser, ADAdminPassword));
                search.Filter = "(&(physicaldeliveryofficename=" + OfficeName + "))";
                //search.PropertiesToLoad.Add(propertyName);
                SearchResultCollection results = search.FindAll();
                if (IsExtProp == true)
                    MakeTableUserExtProp(ref tbUser);
                else
                    MakeTableUserSimple(ref tbUser);
                if (results != null)
                {
                    foreach (SearchResult result in results)
                    {
                        deUser = result.GetDirectoryEntry();
                        strTmp = GetProperty(ref deUser, "USERACCOUNTCONTROL");
                        strOffice = GetProperty(ref deUser, "PHYSICALDELIVERYOFFICENAME");
                        if (IsOnlyActived)
                        {
                            if (!(strTmp == "512" || strTmp == "66048"))
                                continue;
                        }

                        DataRow rwUser = tbUser.NewRow();
                        rwUser["Login"] = GetProperty(ref deUser, "SAMACCOUNTNAME");
                        rwUser["USERACCOUNTCONTROL"] = GetProperty(ref deUser, "USERACCOUNTCONTROL");
                        rwUser["UserName"] = GetProperty(ref deUser, "cn");
                        rwUser["DisplayName"] = GetProperty(ref deUser, "givenName") + " " + GetProperty(ref deUser, "sn");
                        rwUser["EMailAddress"] = GetProperty(ref deUser, "mail");
                        rwUser["Office"] = strOffice;

                        if (IsExtProp == true)
                        {
                            rwUser["SN"] = GetProperty(ref deUser, "SN");
                            rwUser["GIVENNAME"] = GetProperty(ref deUser, "GIVENNAME");
                            rwUser["EXTENSIONATTRIBUTE3"] = GetProperty(ref deUser, "EXTENSIONATTRIBUTE3");
                            rwUser["PHYSICALDELIVERYOFFICENAME"] = GetProperty(ref deUser, "PHYSICALDELIVERYOFFICENAME");
                            rwUser["EXTENSIONATTRIBUTE4"] = GetProperty(ref deUser, "EXTENSIONATTRIBUTE4");
                            rwUser["TELEPHONENUMBER"] = GetProperty(ref deUser, "TELEPHONENUMBER");
                            rwUser["TITLE"] = GetProperty(ref deUser, "TITLE");
                            rwUser["Department"] = GetProperty(ref deUser, "Department");
                            rwUser["Company"] = GetProperty(ref deUser, "Company");
                            rwUser["Manager"] = GetProperty(ref deUser, "Manager");
                        }

                        tbUser.Rows.Add(rwUser);
                        if (deUser != null)
                        {
                            deUser.Close();
                            deUser = null;
                        }
                    }
                }
            }
            catch (Exception err)
            {
                ret = new Exception(err.Message, err);
            }
            finally
            {
                if(deUser != null)
                    deUser.Close();
            }
            return ret;
        }

        public Exception GetUsersInNotOffice(ref DataTable tbUser, string OfficeName, bool IsOnlyActived = true, bool IsExtProp = false)
        {
            string ADServer = GetAppSetting(@"ADServer");
            string ADAdminUser = GetAppSetting(@"ADUser");
            string ADAdminPassword = GetAppSetting(@"ADPass");
            return GetUsersInNotOffice(ref tbUser, ADServer, ADAdminUser, ADAdminPassword, OfficeName, IsOnlyActived, IsExtProp);
        }
        public Exception GetUsersInNotOffice(ref DataTable tbUser, string ADServer, string ADAdminUser, string ADAdminPassword, string OfficeName, bool IsOnlyActived = true, bool IsExtProp = false)
        {
            Exception ret = null;
            DirectoryEntry deUser = null;
            string strTmp = "";
            string strOffice = "";
            try
            {
                DirectorySearcher search =
                    new DirectorySearcher(
                        new DirectoryEntry(ADServer, ADAdminUser, ADAdminPassword));
                search.Filter = "(&(physicaldeliveryofficename=*))";
                //search.PropertiesToLoad.Add(propertyName);
                SearchResultCollection results = search.FindAll();
                if (IsExtProp == true)
                    MakeTableUserExtProp(ref tbUser);
                else
                    MakeTableUserSimple(ref tbUser);
                if (results != null)
                {
                    foreach (SearchResult result in results)
                    {
                        deUser = result.GetDirectoryEntry();
                        strTmp = GetProperty(ref deUser, "USERACCOUNTCONTROL");
                        strOffice = GetProperty(ref deUser, "PHYSICALDELIVERYOFFICENAME");

                        if (strOffice == OfficeName)
                            continue;

                        if (IsOnlyActived)
                        {
                            if (!(strTmp == "512" || strTmp == "66048"))
                                continue;
                        }

                        DataRow rwUser = tbUser.NewRow();
                        rwUser["Login"] = GetProperty(ref deUser, "SAMACCOUNTNAME");
                        rwUser["USERACCOUNTCONTROL"] = GetProperty(ref deUser, "USERACCOUNTCONTROL");
                        rwUser["UserName"] = GetProperty(ref deUser, "cn");
                        rwUser["DisplayName"] = GetProperty(ref deUser, "givenName") + " " + GetProperty(ref deUser, "sn");
                        rwUser["EMailAddress"] = GetProperty(ref deUser, "mail");
                        rwUser["Office"] = strOffice;

                        if (IsExtProp == true)
                        {
                            rwUser["SN"] = GetProperty(ref deUser, "SN");
                            rwUser["GIVENNAME"] = GetProperty(ref deUser, "GIVENNAME");
                            rwUser["EXTENSIONATTRIBUTE3"] = GetProperty(ref deUser, "EXTENSIONATTRIBUTE3");
                            rwUser["PHYSICALDELIVERYOFFICENAME"] = GetProperty(ref deUser, "PHYSICALDELIVERYOFFICENAME");
                            rwUser["EXTENSIONATTRIBUTE4"] = GetProperty(ref deUser, "EXTENSIONATTRIBUTE4");
                            rwUser["TELEPHONENUMBER"] = GetProperty(ref deUser, "TELEPHONENUMBER");
                            rwUser["TITLE"] = GetProperty(ref deUser, "TITLE");
                            rwUser["Department"] = GetProperty(ref deUser, "Department");
                            rwUser["Company"] = GetProperty(ref deUser, "Company");
                            rwUser["Manager"] = GetProperty(ref deUser, "Manager");
                        }

                        tbUser.Rows.Add(rwUser);
                        if (deUser != null)
                        {
                            deUser.Close();
                            deUser = null;
                        }
                    }
                }
            }
            catch (Exception err)
            {
                ret = new Exception(err.Message, err);
            }
            finally
            {
                if (deUser != null)
                    deUser.Close();
            }
            return ret;
        }

        #region Data

        public Exception MakeTableUserSimple(ref DataTable parTbl)
        {
            Exception ret = null;
            if (parTbl != null)
                parTbl = null;
            parTbl = new DataTable("Users");
            parTbl.Columns.Add("Login");
            parTbl.Columns.Add("USERACCOUNTCONTROL");
            parTbl.Columns.Add("UserName");
            parTbl.Columns.Add("DisplayName");
            parTbl.Columns.Add("EMailAddress");
            parTbl.Columns.Add("Office");

            return ret;
        }

        public Exception MakeTableUserExtProp(ref DataTable parTbl)
        {
            Exception ret = null;
            if (parTbl != null)
                parTbl = null;
            parTbl = new DataTable("Users");
            parTbl.Columns.Add("Login"); // SAMACCOUNTNAME
            parTbl.Columns.Add("USERACCOUNTCONTROL");
            parTbl.Columns.Add("UserName");
            parTbl.Columns.Add("DisplayName");
            parTbl.Columns.Add("EMailAddress");
            parTbl.Columns.Add("Office");

            parTbl.Columns.Add("SN");
            parTbl.Columns.Add("GIVENNAME");
            parTbl.Columns.Add("EXTENSIONATTRIBUTE3"); // 
            parTbl.Columns.Add("PHYSICALDELIVERYOFFICENAME");
            parTbl.Columns.Add("EXTENSIONATTRIBUTE4"); // ID1C
            parTbl.Columns.Add("TELEPHONENUMBER");
            parTbl.Columns.Add("TITLE");
            parTbl.Columns.Add("Department");
            parTbl.Columns.Add("Company");
            parTbl.Columns.Add("Manager");

            return ret;
        }

        #endregion

    }

}
